package cn.com.pagoda.ideplugin.ui;

import cn.com.pagoda.ideplugin.service.TimeConversionService;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.ui.popup.PopupStep;
import com.intellij.openapi.ui.popup.util.BaseListPopupStep;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.ui.table.JBTable;
import com.intellij.util.ui.JBUI;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;

/**
 * @author 曾庆苏 on 2023-05-06
 */
public class TimeConversionPanel {
    private final JPanel panel;
    private long unixTimestamp;
    private LocalDateTime localDateTime;
    private final TimeConversionService service;
    private List<String> timeZoneShowList;
    private String currentTimeZoneShow;
    private final JButton selectZoneBtn;
    private final JTextField nowText;
    private final JTextField milliText;
    private final JTextField secondText;
    private final JButton stopBtn;
    private final Timer timer;
    private final JTable table;

    public TimeConversionPanel(AnActionEvent anActionEvent, JPanel mainPanel) {
        this.service = new TimeConversionService();
        this.initData();
        panel = new JPanel(new GridBagLayout());
        panel.setSize(800, 800);
        addLabel("选择时区:", new Dimension(160, 25), createGrid(0, 0));
        selectZoneBtn = addButton(currentTimeZoneShow, new Dimension(280, 25), createGrid(0, 1));

        addLabel(">> Unix时间戳定义", new Dimension(160, 25), createGrid(1, 0));
        addLabel("现在的当地时间为:", new Dimension(160, 25), createGrid(2, 0));
        nowText = addTextField(false, new Dimension(160, 25), createGrid(2, 1));
        stopBtn = addButton("暂停", new Dimension(40, 25), createGrid(2, 2, 1, GridBagConstraints.NONE));
        addLabel("现在的Unix时间戳:", new Dimension(160, 25), createGrid(3, 0));
        secondText = addTextField(false, new Dimension(160, 25), createGrid(3, 1));
        addLabel("秒", new Dimension(40, 25), createGrid(3, 2));
        milliText = addTextField(false, new Dimension(160, 25), createGrid(3, 3));
        addLabel("毫秒", new Dimension(40, 25), createGrid(3, 4));

        addLabel(">> Unix时间戳(毫秒) 转 当地时间(yyyy-MM-dd HH:mm:ss)", new Dimension(250, 25), createGrid(4, 0, 2));
        JTextField inMilliText = addTextField(true, new Dimension(160, 25), createGrid(5, 0));
        JButton milliToLocal = addButton("转换", new Dimension(40, 25), createGrid(5, 1, 1, GridBagConstraints.NONE));
        JTextField outLocalText = addTextField(false, new Dimension(160, 25), createGrid(5, 2));

        addLabel(">> 当地时间(yyyy-MM-dd HH:mm:ss) 转 Unix时间戳(毫秒)", new Dimension(250, 25), createGrid(6, 0, 2));
        JTextField inLocalText = addTextField(true, new Dimension(160, 25), createGrid(7, 0));
        JButton localToUnix = addButton("转换", new Dimension(40, 25), createGrid(7, 1, 1, GridBagConstraints.NONE));
        JTextField outUnixText = addTextField(false, new Dimension(160, 25), createGrid(7, 2));

        addLabel(">> 世界时钟", new Dimension(160, 25), createGrid(8, 0));
        JButton reBtn = addButton("刷新", new Dimension(40, 25), createGrid(8, 1, 1, GridBagConstraints.NONE));
        table = new JBTable();
        table.setDefaultEditor(Object.class, null);
        table.setCellSelectionEnabled(true);
        table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        updateTable(table);
        JBScrollPane jbScrollPane = new JBScrollPane();
        jbScrollPane.setPreferredSize(new Dimension(500, 400));
        jbScrollPane.setViewportView(table);
        panel.add(jbScrollPane, createGrid(9, 0, 4, GridBagConstraints.HORIZONTAL));
        mainPanel.add(panel, getClass().getSimpleName());

        selectZoneBtn.addActionListener(e -> showTimeZonePopup());

        this.timer = new Timer(500, e -> timerRefresh());
        this.timer.start();

        stopBtn.addActionListener(e -> {
            if (timer.isRunning()) {
                timer.stop();
                stopBtn.setText("恢复");
            } else {
                timer.start();
                stopBtn.setText("暂停");
            }
        });

        localToUnix.addActionListener(e -> outUnixText.setText(service.localDateTimeStr2Milli(inLocalText.getText(), getTimeZone(currentTimeZoneShow))));

        milliToLocal.addActionListener(e -> outLocalText.setText(service.milli2LocalDateTimeStr(Long.parseLong(inMilliText.getText()), getTimeZone(currentTimeZoneShow))));

        reBtn.addActionListener(e -> updateTable(table));
    }

    private GridBagConstraints createGrid(int y, int x) {
        return createGrid(y, x, 1, GridBagConstraints.HORIZONTAL);
    }

    private GridBagConstraints createGrid(int y, int x, int w) {
        return createGrid(y, x, w, GridBagConstraints.HORIZONTAL);
    }

    private GridBagConstraints createGrid(int y, int x, int w, int fill) {
        GridBagConstraints c = new GridBagConstraints();
        c.gridy = y;
        c.gridx = x;
        c.gridwidth = w;
        c.fill = fill;
        c.insets = JBUI.insets(5);
        return c;
    }

    private void addLabel(String text, Dimension dimension, GridBagConstraints constraints) {
        JLabel label = new JLabel(text);
        label.setPreferredSize(dimension);
        panel.add(label, constraints);
    }

    private JButton addButton(String text, Dimension dimension, GridBagConstraints constraints) {
        JButton button = new JButton(text);
        button.setPreferredSize(dimension);
        panel.add(button, constraints);
        return button;
    }

    private JTextField addTextField(boolean editable, Dimension dimension, GridBagConstraints constraints) {
        JTextField textField = new JTextField();
        textField.setEditable(editable);
        textField.setPreferredSize(dimension);
        panel.add(textField, constraints);
        return textField;
    }

    /**
     * 时区下拉选择
     */
    private void showTimeZonePopup() {
        JBPopupFactory.getInstance().createListPopup(
                new BaseListPopupStep<>("选择一个时区", timeZoneShowList) {
                    @Override
                    public PopupStep onChosen(String selectedValue, boolean finalChoice) {
                        selectZoneBtn.setText(selectedValue);
                        currentTimeZoneShow = selectedValue;
                        timerRefresh();
                        updateTable(table);
                        return super.onChosen(selectedValue, finalChoice);
                    }
                }
        ).showUnderneathOf(selectZoneBtn);
    }

    private void initData() {
        timeZoneShowList = Arrays.asList(
                "Asia/Shanghai - [亚洲] 中国/上海",
                "Asia/Tokyo - [亚洲] 日本/东京",
                "Asia/Singapore - [亚洲] 新加坡",
                "Asia/Bangkok - [亚洲] 泰国/曼谷",
                "Asia/Colombo - [亚洲] 印度/斯里兰卡/科伦坡",
                "Asia/Kabul - [亚洲] 阿富汗/喀布尔",
                "Asia/Baghdad - [亚洲] 伊拉克/巴格达",
                "Asia/Dubai - [亚洲] 阿联/迪拜",
                "Europe/Moscow - [欧洲] 俄罗斯/莫斯科",
                "Europe/Paris - [欧洲] 法国/巴黎",
                "Europe/Berlin - [欧洲] 德国/柏林",
                "Europe/London - [欧洲] 英国/伦敦",
                "Europe/Dublin - [欧洲] 爱尔兰/都柏林",
                "Europe/Istanbul - [欧洲] 土耳其/伊斯坦布尔",
                "Europe/Bucharest - [欧洲] 罗马尼亚/布加勒斯",
                "America/Los_Angeles - [北美洲] 美国/洛杉矶",
                "America/New_York - [北美洲] 美国/纽约",
                "America/Lima - [南美洲] 秘鲁/利马",
                "America/Sao_Paulo - [南美洲] 巴西/圣保罗",
                "Australia/Sydney - [大洋洲] 澳大利亚/悉尼",
                "Pacific/Auckland - [大洋洲] 新西兰/奥克兰",
                "Africa/Nairobi - [非洲] 肯尼亚/内罗毕",
                "Africa/Lagos - [非洲] 尼日利亚/拉各斯");
        //初始化默认数据
        currentTimeZoneShow = timeZoneShowList.get(0);
        unixTimestamp = service.getUnixTimestamp();
        localDateTime = service.milli2LocalDateTime(unixTimestamp, getTimeZone(currentTimeZoneShow));
    }

    private void updateTable(JTable table) {
        DefaultTableModel model = new DefaultTableModel();
        String[] columnNames = {"时区", "时间"};
        model.setColumnIdentifiers(columnNames);
        for (String value : timeZoneShowList) {
            model.addRow(new String[]{value, service.milli2LocalDateTimeStr(service.getUnixTimestamp(), getTimeZone(value))});
        }
        table.setModel(model);
    }

    private void timerRefresh() {
        unixTimestamp = service.getUnixTimestamp();
        localDateTime = service.milli2LocalDateTime(unixTimestamp, getTimeZone(currentTimeZoneShow));
        nowText.setText(service.getLocalDateTimeStr(localDateTime));
        milliText.setText(String.valueOf(unixTimestamp));
        secondText.setText(String.valueOf(unixTimestamp / 1000));
    }

    private String getTimeZone(String timeZoneShow) {
        return timeZoneShow.split("-")[0].trim();
    }
}